﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.HtmlControls;
using System.Windows.Forms;
using Npgsql;
using Ortodoctor.Componentes;
using System.Web;

namespace Ortodoctor.modelo
{
    class modeloProcedimentoCliente : conexao
    {
        public modeloProcedimentoCliente()
        {
            conn = new NpgsqlConnection(connectionstring);
            conn.Open();
        }

        public int insert(Procedimento_Cliente p)
        {
            int dt = 0;
            
            try
            {
                //con.open();
                String sql = @"INSERT INTO procedimento_cliente(id_procedimento, id_cliente, valor_total, 
                         tempo_tratamento, id_funcionario) VALUES (:p1, :p2, :p3, :p4, :p5)";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("p1", p.IdProcedimento);
                com.Parameters.AddWithValue("p2", p.IdCliente);
                com.Parameters.AddWithValue("p3", p.ValorTotal.ToString().Replace(",", "."));
                com.Parameters.AddWithValue("p4", p.TempoTratamento);
                com.Parameters.AddWithValue("p5", p.IdDentista);
                com.ExecuteNonQuery();

                dt = Convert.ToInt32(selectMaxId().Rows[0][0]);
            }

            finally
            {
                conn.Close();
            }
            return dt;
        }

        public DataTable selectMaxId(bool close = true)
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                String sql = "select max(id_procedimento_cliente) from procedimento_cliente";
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
                da.Fill(dt);
                if (dt.Rows[0][0] == DBNull.Value)
                    dt.Rows[0][0] = 0;
            }
            finally
            {
                if (close)
                    conn.Close();
            }

            return dt;
        }

        public DataTable getAll()
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();

                //bruno mudou a antiga eh essa abaixo
                //                String sql = @"SELECT PROCEDIMENTO_CLIENTE.*, 
                //                                  PROCEDIMENTO.NOME_PROCEDIMENTO, 
                //                                  CLIENTE.NOME, 
                //                                  A.VALOR AS VALOR_PARCELA, 
                //                                  A.DIA_VENCIMENTO 
                //                            FROM PROCEDIMENTO INNER JOIN 
                //                                 PROCEDIMENTO_CLIENTE USING(ID_PROCEDIMENTO) INNER JOIN 
                //CLIENTE USING(ID_CLIENTE) INNER JOIN 
                //(SELECT DISTINCT VALOR, 
                //    ID_PROCEDIMENTO_CLIENTE, 
                //    max(extract(day from data_vencimento)) as dia_vencimento 
                //FROM PARCELAS group by valor, id_procedimento_cliente) A USING(ID_PROCEDIMENTO_CLIENTE)";

                //a nova eh essa abaixo
                String sql = @"select pc.*, p.nome_procedimento, c.nome, cast(vp.valor_parcela as decimal (18,2)) as valor_parcela, max(extract(day from par.data_vencimento)) as dia_vencimento 
                 from procedimento_cliente as pc inner join cliente as c using(id_cliente) 
                 inner join procedimento as p using (id_procedimento) inner join parcelas as par 
                 using (id_procedimento_cliente) inner join (select avg(valor) as valor_parcela, id_procedimento_cliente 
                 from parcelas as valor_parcela group by valor_parcela.id_procedimento_cliente) as vp using (id_procedimento_cliente) 
                 group by pc.id_procedimento, pc.id_cliente, pc.valor_total, 
                 pc.tempo_tratamento, pc.id_procedimento_cliente, c.nome, p.nome_procedimento, vp.valor_parcela";

                if (HttpContext.Current.Session["USUARIO_ACESSO"].ToString().CompareTo("2") != 0)
                {
                    sql = "select pc.*, p.nome_procedimento, c.nome, cast(vp.valor_parcela as decimal (18,2)) as valor_parcela, max(extract(day from par.data_vencimento)) as dia_vencimento "
                + " from procedimento_cliente as pc inner join cliente as c using(id_cliente) "
                + " inner join clinica using (id_clinica) "
                + " inner join procedimento as p using (id_procedimento) inner join parcelas as par "
                + " using (id_procedimento_cliente) inner join (select avg(valor) as valor_parcela, id_procedimento_cliente "
                + " from parcelas as valor_parcela group by valor_parcela.id_procedimento_cliente) as vp using (id_procedimento_cliente) "
                + " where id_clinica=" + HttpContext.Current.Session["ID_CLINICA"]
                + " group by pc.id_procedimento, pc.id_cliente, pc.valor_total, "
                + " pc.tempo_tratamento, pc.id_procedimento_cliente, c.nome, p.nome_procedimento, vp.valor_parcela";
                }

                NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            return dt;
        }

        public DataTable getProcedimentoCliente(int id, bool close = true)
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                //String sql = "SELECT PROCEDIMENTO_CLIENTE.*, PROCEDIMENTO.NOME_PROCEDIMENTO, CLIENTE.NOME FROM PROCEDIMENTO INNER JOIN PROCEDIMENTO_CLIENTE USING(ID_PROCEDIMENTO) INNER JOIN CLIENTE USING(ID_CLIENTE) " +
                //             "WHERE id_procedimento_cliente=:id";
                String sql = "SELECT PROCEDIMENTO_CLIENTE.*, PROCEDIMENTO.NOME_PROCEDIMENTO, CLIENTE.NOME, FUNCIONARIO.NOME as NOME_FUNCIONARIO FROM PROCEDIMENTO INNER JOIN PROCEDIMENTO_CLIENTE USING(ID_PROCEDIMENTO) INNER JOIN CLIENTE USING(ID_CLIENTE) INNER JOIN FUNCIONARIO USING(ID_FUNCIONARIO) WHERE id_procedimento_cliente=:id";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", id);
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(com);
                da.Fill(dt);

                if (dt.Rows.Count == 0)
                {
                    String sql2 = "SELECT PROCEDIMENTO_CLIENTE.*, PROCEDIMENTO.NOME_PROCEDIMENTO, CLIENTE.NOME FROM PROCEDIMENTO INNER JOIN PROCEDIMENTO_CLIENTE USING(ID_PROCEDIMENTO) INNER JOIN CLIENTE USING(ID_CLIENTE) " +
                             "WHERE id_procedimento_cliente=:id";
                    NpgsqlCommand com2 = new NpgsqlCommand(sql2, conn);
                    com2.Parameters.AddWithValue("id", id);
                    NpgsqlDataAdapter da2 = new NpgsqlDataAdapter(com2);
                    dt = new DataTable();
                    da2.Fill(dt);
                }
            }
            finally
            {
                if (close)
                    conn.Close();
            }
            return dt;
        }

        public void update(Procedimento_Cliente p)
        {
            try
            {
                //con.open();
                String sql = "UPDATE procedimento_cliente SET id_funcionario=:id_funcionario, id_procedimento=:p2, valor_total=:p1, id_usuario_modificacao=:id_mod WHERE id_procedimento_cliente=:id";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id_funcionario", p.IdDentista);
                com.Parameters.AddWithValue("p1", p.ValorTotal);
                com.Parameters.AddWithValue("p2", p.IdProcedimento);
                com.Parameters.AddWithValue("id", p.IdProcedimentoCliente);
                com.Parameters.AddWithValue("id_mod", HttpContext.Current.Session["ID_USUARIO_ACESSO"].ToString());
                com.ExecuteNonQuery();
            }
            finally
            {
                conn.Close();
            }
        }

        public void delete(int id)
        {
            try
            {
                //con.open();
                String sql = "DELETE FROM procedimento_cliente WHERE id_procedimento_cliente=:id";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", id);
                com.ExecuteNonQuery();


                sql = "update procedimento_cliente_hist set id_usuario_modificacao=:id_mod, data_modificacao=:data WHERE id_procedimento_cliente=:id";
                com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id_mod", HttpContext.Current.Session["ID_USUARIO_ACESSO"].ToString());
                com.Parameters.AddWithValue("data", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"));
                com.Parameters.AddWithValue("id", id);
                com.ExecuteNonQuery();

                sql = "DELETE FROM parcelas WHERE id_procedimento_cliente=:id";
                com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", id);
                com.ExecuteNonQuery();

                sql = "update parcelas_hist set id_usuario_modificacao=:id_mod, data_modificacao=:data WHERE id_procedimento_cliente=:id";
                com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id_mod", HttpContext.Current.Session["ID_USUARIO_ACESSO"].ToString());
                com.Parameters.AddWithValue("data", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"));
                com.Parameters.AddWithValue("id", id);
                com.ExecuteNonQuery();
            }
            finally
            {
                conn.Close();
            }
        }

        internal DataTable getProcCliente(int p)
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                String sql = "select procedimento_cliente.* from procedimento_cliente where id_cliente = :id";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", p);
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(com);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            return dt;
        }

        internal bool getProcCliente(int procedimento, int cliente)
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                String sql = @"SELECT * FROM PROCEDIMENTO_CLIENTE 
		                                    WHERE ID_PROCEDIMENTO  = :procedimento
		                                      AND ID_CLIENTE       = :cliente";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("procedimento", procedimento);
                com.Parameters.AddWithValue("cliente", cliente);
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(com);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            return dt == null || dt.Rows.Count == 0 ? false : true;
        }

        internal DataTable getProcClienteIndicacao(int p, bool orto = false)
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                String sql = "SELECT PROCEDIMENTO_CLIENTE.* FROM PROCEDIMENTO_CLIENTE INNER JOIN PROCEDIMENTO USING(ID_PROCEDIMENTO) WHERE " + (orto ? " UPPER(TIPO) = 'ORTODONTICO' AND " : "") + " ID_CLIENTE = :id AND PROMOCAO = 'Sim'";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", p);
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(com);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            return dt;
        }

        public DataTable getProcClienteCarne()
        {
            DataTable dt = new DataTable();
            try
            {
                string sql = @"select pc.*, p.nome_procedimento, c.nome, vp.valor_parcela, max(extract(day from par.data_vencimento)) as dia_vencimento 
                                from procedimento_cliente as pc inner join cliente as c using(id_cliente) 
                                inner join procedimento as p using (id_procedimento) inner join parcelas as par 
                                using (id_procedimento_cliente) inner join (select avg(valor) as valor_parcela, id_procedimento_cliente 
                                from parcelas as valor_parcela group by valor_parcela.id_procedimento_cliente) as vp using (id_procedimento_cliente) 
                                where carne = false 
                                group by pc.id_procedimento, pc.id_cliente, pc.valor_total, 
                                pc.tempo_tratamento, pc.id_procedimento_cliente, c.nome, p.nome_procedimento, vp.valor_parcela";
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            return dt;
        }

        public void updateCarne(int id)
        {
            try
            {
                //con.open();
                String sql = "UPDATE procedimento_cliente SET carne=true, id_usuario_modificacao=:id_mod WHERE id_procedimento_cliente=:id";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("id", id);
                com.Parameters.AddWithValue("id_mod", HttpContext.Current.Session["ID_USUARIO_ACESSO"].ToString());
                com.ExecuteNonQuery();
            }
            finally
            {
                conn.Close();
            }
        }

        internal DataTable getProcedimentoRelatorio(string p1, string p2, string p3, string p4)
        {
            DataTable dt = new DataTable();
            try
            {
                string sql = "";
                if (p1 == null || string.IsNullOrEmpty(p1.ToString()))
                {

                    sql = string.Format(@"
                                            SELECT ENDERECO.CIDADE,
                                                   FUNCIONARIO.NOME,
                                                   CLIENTE.NOME as ""Paciente"",
                                                   PROCEDIMENTO.NOME_PROCEDIMENTO,
	                                               CAST(COMPARECIMENTO.DATA AS VARCHAR) AS ""Data""
                                            FROM PROCEDIMENTO_CLIENTE INNER JOIN
                                                 PROCEDIMENTO USING(ID_PROCEDIMENTO) INNER JOIN
                                                 CLIENTE USING(ID_CLIENTE) INNER JOIN 
                                                 CLINICA USING(ID_CLINICA) INNER JOIN 
                                                 ENDERECO ON ENDERECO.ID_ENDERECO = CLINICA.ID_ENDERECO INNER JOIN
                                                 COMPARECIMENTO ON CLIENTE.ID_CLIENTE = COMPARECIMENTO.ID_CLIENTE INNER JOIN
                                                 FUNCIONARIO ON FUNCIONARIO.ID_FUNCIONARIO = COMPARECIMENTO.ID_DENTISTA
                                            WHERE COMPARECIMENTO.DATA <= NOW() AND
                                                  (CLINICA.ID_CLINICA = {0} OR {0} = -999) AND
                                                  (FUNCIONARIO.ID_FUNCIONARIO = {1} OR {1} = -999) ORDER BY 
                                            COMPARECIMENTO.DATA",
                                                p3,
                                                p4);
                }
                else
                {
                    sql = string.Format(@"
                                            SELECT ENDERECO.CIDADE AS ""Clínica"",
                                                   FUNCIONARIO.NOME AS ""Dentista"",
                                                   CLIENTE.NOME AS ""Paciente"",
                                                   PROCEDIMENTO.NOME_PROCEDIMENTO AS ""Tratamento"",
	                                               CAST(COMPARECIMENTO.DATA AS VARCHAR) AS ""Data""
                                            FROM PROCEDIMENTO_CLIENTE INNER JOIN
                                                 PROCEDIMENTO USING(ID_PROCEDIMENTO) INNER JOIN
                                                 CLIENTE USING(ID_CLIENTE) INNER JOIN 
                                                 CLINICA USING(ID_CLINICA) INNER JOIN 
                                                 ENDERECO ON ENDERECO.ID_ENDERECO = CLINICA.ID_ENDERECO INNER JOIN
                                                 COMPARECIMENTO ON CLIENTE.ID_CLIENTE = COMPARECIMENTO.ID_CLIENTE INNER JOIN
                                                 FUNCIONARIO ON FUNCIONARIO.ID_FUNCIONARIO = COMPARECIMENTO.ID_DENTISTA
                                            WHERE COMPARECIMENTO.DATA <= NOW() AND
                                                  COMPARECIMENTO.DATA BETWEEN '{0}' AND '{1}' AND 
                                                  (CLINICA.ID_CLINICA = {2} OR {2} = -999) AND
                                                  (FUNCIONARIO.ID_FUNCIONARIO = {3} OR {3} = -999) ORDER BY 
                                            COMPARECIMENTO.DATA",
                                                Convert.ToDateTime(p1).ToString("MM/dd/yyyy"),
                                                Convert.ToDateTime(p2).ToString("MM/dd/yyyy"),
                                                p3,
                                                p4);
                }
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
                da.Fill(dt);

                foreach (DataRow dr in dt.Rows)
                    dr["Data"] = Convert.ToDateTime(dr["Data"]).ToString("dd/MM/yyyy");
            }
            finally
            {
                conn.Close();
            }
            return dt;
        }

        public string getContrato()
        {
            DataTable dt = new DataTable();
            try
            {
                //con.open();
                String sql = "SELECT VALOR FROM CONFIGURACOES WHERE PARAMETRO = 'CONTRATO'";
                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(com);
                da.Fill(dt);
            }
            finally
            {
                conn.Close();
            }
            try
            {
                return dt.Rows[0]["VALOR"].ToString();
            }
            catch (Exception) { return ""; }
        }

        public void Log(string operacao, string log)
        {
            DateTime dt = DateTime.Now;
            try
            {
                String sql = @"INSERT INTO procedimento_cliente_log(operacao, log, data) values (:p1, :p2, :p3)";

                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("p1", operacao);
                com.Parameters.AddWithValue("p2", log);
                com.Parameters.AddWithValue("p3", DateTime.Now.ToShortDateString() + " - " + DateTime.Now.ToShortTimeString());
                com.ExecuteScalar();
            }
            finally
            {
                conn.Close();
            }
        }

        internal void updateNumParcelas(int num, int id, string valor)
        {
            try
            {
                String sql = @"UPDATE procedimento_cliente SET tempo_tratamento = tempo_tratamento + :p1, valor_total = valor_total + (:p1 * :p3) where id_procedimento_cliente = :p2";

                NpgsqlCommand com = new NpgsqlCommand(sql, conn);
                com.Parameters.AddWithValue("p1", num);
                com.Parameters.AddWithValue("p2", id);
                com.Parameters.AddWithValue("p3", valor);
                com.ExecuteScalar();
            }
            finally
            {
                conn.Close();
            }
        }
    }
}
